﻿using Ivory;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
using CrystalCore.AI;
using CrystalCore.Mapping;

namespace CrystalCore.Libs
{
    public abstract class Camera : IPathableEntity
    {
        //Fields
        public Game Game { get; set; }

		private Vector3 _CameraPosition; 
		public Vector3 CameraPosition
		{
			get { return _CameraPosition; }
			set { _CameraPosition = value; }
		} 
            
		private Vector3 _CameraLookAt; 
		public Vector3 CameraLookAt
		{
			get { return _CameraLookAt; }
			set { _CameraLookAt = value; }
		} 
 
		private float _CameraMoveSpeed = 1f; 
		public float CameraMoveSpeed
		{
			get { return _CameraMoveSpeed; }
			set { _CameraMoveSpeed = value; }
		} 		
 
		private float _FoV = MathHelper.PiOver4;
		public float FoV
		{
			get { return _FoV; }
			set { _FoV = value; }
		}
 
		private float _NearPlane = 1f; 
		public float NearPlane
		{
			get { return _NearPlane; }
			set { _NearPlane = value; }
		} 
 
		private float _FarPlane = 300f; 
		public float FarPlane
		{
			get { return _FarPlane; }
			set { _FarPlane = value; }
		} 
		
        public Matrix View 
        {
            get
            {
                return Matrix.CreateLookAt(CameraPosition, CameraLookAt, Vector3.Up);
            }
        }
        public Matrix Projection
        {
            get
            {
                return Matrix.CreatePerspectiveFieldOfView(FoV, Game.GraphicsDevice.Viewport.AspectRatio, NearPlane, FarPlane);
            }
        }		

        //cTor
        public Camera(Game game, Vector3 Position, Vector3 Target) 
        {
            this.Game = game;
            this.CameraPosition = Position;
            this.CameraLookAt = Target;
        }

        //Methods
        public abstract void UpdateCamera(InputControl input, GameTime time);

        public void DefaultCameraAction(InputControl input)
        {
            #region MoveControl V1
            Vector3 MoveDir = Vector3.Zero;
            if (input.IsKeyDown(Keys.W))
                MoveDir.Z += 1;
            else if (input.IsKeyDown(Keys.S))
                MoveDir.Z -= 1;

            if (input.IsKeyDown(Keys.A))
                MoveDir.X += 1;
            else if (input.IsKeyDown(Keys.D))
                MoveDir.X -= 1;

            if (input.IsKeyDown(Keys.Add))
                MoveDir.Y += 1;
            else if (input.IsKeyDown(Keys.Subtract))
                MoveDir.Y -= 1;

            if (MoveDir != Vector3.Zero)
            {
                MoveDir.Normalize();
                MoveDir *= CameraMoveSpeed;
                CameraPosition += MoveDir;
                CameraLookAt += MoveDir;
            }
            #endregion
        }

        #region PathableEntity
        public virtual Vector3 EntityPosition
        {
            get { return CameraPosition; }
            set
            {
                CameraPosition = value;
                //HandleCameraMoveOnPath();
            }
        }
        public virtual float ActorSpeed
        {
            get { return CameraMoveSpeed; }
        }
        public virtual bool IsControlled
        {
            get;
            set;
        }
        public virtual float Rotation
        {
            get; 
            set;
        }
        #endregion
    }
}
